
#include "JsonLexParser.h"
#include "JsonParserObject.h"
#include <iostream>
// Json 语法

//     program_start = object Token_END_DOC | array Token_END_DOC

//     object = {} | { members }
//     members = pair | pair , members
//     pair = string : value
//     array = [] | [ elements ]
//     elements = value  | value , elements
//     value = string | number | object | array | true | false | null

// 当全局前变量
extern JsonObject * final_JsonObject ;
extern JsonArray *  final_JsonArray ;
// 函数
int f_program_start();
void match(Token t);
JsonObject * f_object();
void f_members(JsonObject &);
void f_pair(JsonObject &);
JsonArray * f_array();
void f_elements(JsonArray &);
Value * f_value();




//map<char *, int, ptrCmp> mapStr;


// void is_Token_Value
// {
//     if(currToken == Token_STRING || currToken == Token_INTNUMBER || currToken == )
// }
void match(Token t)
{
    if(t!=currToken)
    {
        exit(0);
    }
}

//     program_start = object Token_END_DOC | array Token_END_DOC
int f_program_start()
{
    getNextChar();
    getToken();
    if(currToken == Token_START_ARRAY)
    {
        final_JsonArray = f_array();
        //getToken();
        match(Token_END_DOC);
        std::cout<<"grammer parse finish"<<std::endl;
        return 2;
    }
    else if(currToken == Token_START_OBJ)
    {
        final_JsonObject = f_object();
        //getToken();
        match(Token_END_DOC);
        std::cout<<"grammer parse finish"<<std::endl;
        return 1;
    }
    else
    {
        exit(0);
        return 0;
    }
}

//     object = {} | { members }
JsonObject * f_object()
{
    JsonObject * ptempObject = (JsonObject *) malloc(sizeof(JsonObject));
    match(Token_START_OBJ);
    getToken();
    if (currToken != Token_END_OBJ)
    {
        f_members(*ptempObject);
    }
    //getToken();
    match(Token_END_OBJ);
    getToken();

    return ptempObject;
}

//  
//members = pair | pair , members
void f_members(JsonObject & tempObject)
{
    f_pair(tempObject);
    //getToken();
    if(currToken == Token_COMMA)
    {
        getToken();
        f_members(tempObject); 
    }      
}

//     pair = string : value
void f_pair(JsonObject & tempObject)
{   
    if(currToken == Token_STRING)
    {
        char* key = (char*) malloc((strlen(currString) + 1));
        //std::cout<<strlen(currString)<<endl;
        strcpy(key,currString);
        //std::cout<<strlen(key)<<endl;
        getToken();
        match(Token_COLON);
        getToken();
        Value* pVa = f_value();
       
        // printf("%s :",key);
        // printValue(*pVa,0);
        // std::cout<<endl;
        tempObject.put(key,pVa);
        //free(key);
    }
    else
    {
        exit(0);
    } 
}

//     array = [] | [ elements ]
JsonArray * f_array()
{
    JsonArray * ptempArray = (JsonArray *) malloc(sizeof(JsonArray));

    match(Token_START_ARRAY);
    getToken();
    if (currToken != Token_END_ARRAY)
    {
        f_elements(* ptempArray);
    }
    match(Token_END_ARRAY);
    getToken();
    
    return ptempArray;
}

//     elements = value  | value , elements

void f_elements(JsonArray & tempArray)
{
    Value* pVa = f_value();
    
    tempArray.put(pVa);
    
    //getToken();
    if(currToken == Token_COMMA)
    {
        getToken();
        f_elements(tempArray);
    }
}
//     value = string | number | object | array | true | false | null
Value* f_value()
{
    Value * pVa  = (Value*) malloc(sizeof(Value));
    switch (currToken)
    {
        case Token_STRING:
        {   //语义动作
            pVa->String =  (char*) malloc(sizeof(char)*(strlen(currString) + 1));
            //pVa->String.assign(currString);
            strcpy(pVa->String,currString);
            
            pVa->type = STRING;
            //语法动作
            getToken(); 
            break;
        }
        case Token_INTNUMBER:
        {  
            //语义动作
            pVa->i_number = currIntNumber;
            pVa->type = I_NUMBER;
            //语法动作
            getToken(); 
            break;
        }
        case Token_FLOATNUMBER:
        {   //语义动作
            pVa->f_number = currFloatNumber;
            pVa->type = F_NUMBER;
            //语法动作
            getToken();  
            break;
        }
        case Token_BOOLEAN:
        {   
            //语义动作
            pVa->bool_value = currBoolValue;
            pVa->type = Value_Bool;
            //语法动作
            getToken(); 
            break;
        }
        case Token_START_ARRAY:
        {   
            //语义动作
            pVa->Json_Array = f_array();
            pVa->type = ARRAY;
            break;
        }
        case Token_START_OBJ:
        {
            //语义动作
            //语法动作
            pVa->Json_Object = f_object();
            pVa->type = OBJECT;
            break;
        }
    }
    return pVa;
}